/**
 * @file uri.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2024-04-01
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#ifndef JSASM_STRINGS_URI_H_
#define JSASM_STRINGS_URI_H_
#include <sys/types.h>

#include "src/base/bit-field.h"
#include "src/common/globals.h"

namespace unibrow {

using uchar = unsigned int;
using byte = unsigned char;

const int kMaxMappingSize = 4;

#ifndef JSASM_INTL_SUPPORT

template <class T, int size = 256>
class Predicate {
    public:
        inline Predicate() = default;
        inline bool get(uchar c);

    private:
        friend class Test;
        
        bool CalculateValue(uchar c);

        class CacheEntry {
            public:
                inline CacheEntry()
                    : bit_field__(CodePointField::encode(0) | ValueField::encode(0)) {}
                inline CacheEntry(uchar code_point, bool value)
                    : bit_field_(CodePointField::encode(CodePointField::kMask & code_point) | 
                        ValueField::encode(value)) {

                }

                uchar code_point() const { return CodePointField::decode(bit_field_); }

                bool value() const { return ValueField::decode(bit_field_); }

            private:
                using CodePointField = base::BitField<uchar, 0, 21>;
                using ValueField = base::BitField<bool, 21, 1>;

                uint32_t bit_field_;
        };

        static const int kSize = size;
        static const int kMask = kSize - 1;
        CacheEntry entries_[kSize];
};

template <class T, int size = 256>
class Mapping {
    public:
        inline Mapping() = default;
        inline int get(uchar c, uchar n, uchar* result);

    private:
        friend class Test;
        int CalculateValue(uchar c, uchar n, uchar* result);

        struct CacheEntry {
            inline CacheEntry() : code_point_(kNoChar), offset_(0) {}
            inline CacheEntry(uchar code_point, signed offset) : code_point_(code_point), offset_(offset) {}
        };
};

#endif // JSASM_INTL_SUPPORT

} // namespace strings

#endif // JSASM_STRINGS_URI_H_